package spring.aop.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;

/**
 * description: 定义四个增强方法,获取目标方法的信息 返回值 异常对象
 *
 * 1.定义方法 - 增强代码
 * 2.使用注解指定对应的位置
 * 3.配置切点表达式选中方法
 * 4.切面和ioc的配置
 * 5.开启aspectj注解的支持
 *
 * TODO: 增强方法中获取目标方法信息
 *     1. 通过增强方法的形参 (JoinPoint jointPoint) 获取目标方法的信息
 *        用于全部的增强方法中，可以获取插入点的方法名、参数、访问修饰符、所属类信息等
 *        注意导入的是AspectJ的包 import org.aspectj.lang.JoinPoint;
 *     2. 通过增强方法的形参 (Object result) 获取目标方法的返回结果
 *        只能在 @AfterReturning 方法下
 *        通过注解参数指定接收结果的形参参数名 @AfterReturning(value = "execution(* com..impl.*.*(..))",returning = "形参名")
 *     3. 通过增强方法的形参 (Throwable t) 获取目标方法的异常信息
 *        只能在 @AfterThrowing 方法下
 *        通过注解参数指定接收异常的形参参数名 @AfterThrowing(value = "execution(* com..impl.*.*(..))",throwing = "形参名")
 */

@Component
@Aspect
public class MyAdvice {

    @Before("spring.aop.pointcut.MyPointCut.myPc()")
    public void before(JoinPoint joinPoint){

        // 方法的签名包括方法的全部声明信息
        Signature signature = joinPoint.getSignature();

        // 获取方法访问修饰符，返回数字int后转为字符串
        int modifiers = joinPoint.getSignature().getModifiers();
        String s = Modifier.toString(modifiers);

        //获取方法名称
        String name = signature.getName();

        //获取参数列表, 数组直接打印看不到具体数据，转换为List集合
        Object[] args = joinPoint.getArgs();
        List<Object> argList = Arrays.asList(args);

        //获取方法所属类的信息
        String simpleName = joinPoint.getTarget().getClass().getSimpleName();

    }

    @AfterReturning(value = "spring.aop.pointcut.MyPointCut.myPc()", returning = "result")
    public void afterReturning(JoinPoint jointPoint, Object result){

    }

    @After("spring.aop.pointcut.MyPointCut.myPc()")
    public void after(JoinPoint jointPoint){

    }

    @AfterThrowing(value = "execution(* com..impl.*.*(..))", throwing = "throwable")
    public void afterThrowing(JoinPoint jointPoint, Throwable throwable){

    }

}
